00001 /* 00002 * Copyright (c) 2013 Battelle Memorial Institute 00003 * Licensed under modified BSD License. A copy of this license can be found 00004 * in the LICENSE file in the top level directory of this distribution. 00005 */ 00006 // ------------------------------------------------------------- 00007 /** 00008 * @file base_component.hpp 00009 * @author Bruce Palmer 00010 * @date 2016-07-14 13:50:54 d3g096 00011 * 00012 * @brief 00013 * 00014 * 00015 */ 00016 // ------------------------------------------------------------- 00017 00018 #ifndef _base_component_h_ 00019 #define _base_component_h_ 00020 00021 #include <vector> 00022 #include <boost/serialization/base_object.hpp> 00023 #include <boost/serialization/split_member.hpp> 00024 00025 #include "boost/smart_ptr/shared_ptr.hpp" 00026 #include "boost/smart_ptr/weak_ptr.hpp" 00027 #include "gridpack/utilities/complex.hpp" 00028 #include "gridpack/component/data_collection.hpp" 00029 00030 #include <boost/serialization/export.hpp> 00031 00032 // TODO: Might want to put MatrixIndices and VectorIndex operations into a 00033 // separate class since these can probably be implemented once for all 00034 // network components 00035 namespace gridpack{ 00036 namespace component{ 00037 00038 class MatVecInterface { 00039 public: 00040 /** 00041 * Constructor 00042 */ 00043 MatVecInterface(void); 00044 00045 /** 00046 * Destructor 00047 */ 00048 virtual ~MatVecInterface(void); 00049 00050 /** 00051 * Return size of matrix block on the diagonal contributed by component 00052 * @param isize,jsize number of rows and columns of matrix 00053 * block 00054 * @return false if network component does not contribute 00055 * matrix element 00056 */ 00057 virtual bool matrixDiagSize(int *isize, int *jsize) const; 00058 00059 /** 00060 * Return the values for a diagonal matrix block. The values are 00061 * returned in row-major order. 00062 * @param values pointer to matrix block values 00063 * @return false if network component does not contribute 00064 * matrix element 00065 */ 00066 virtual bool matrixDiagValues(ComplexType *values); 00067 virtual bool matrixDiagValues(RealType *values); 00068 00069 /** 00070 * Return size of off-diagonal matrix block contributed by component. The 00071 * values are for the forward direction. 00072 * @param isize,jsize number of rows and columns of matrix 00073 * block 00074 * @return false if network component does not contribute 00075 * matrix element 00076 */ 00077 virtual bool matrixForwardSize(int *isize, int *jsize) const; 00078 00079 /** 00080 * Return the values for an off-diagonl matrix block. The values are 00081 * for the forward direction and are returned in row-major order. 00082 * @param values pointer to matrix block values 00083 * @return false if network component does not contribute 00084 * matrix element 00085 */ 00086 virtual bool matrixForwardValues(ComplexType *values); 00087 virtual bool matrixForwardValues(RealType *values); 00088 00089 /** 00090 * Return size of off-diagonal matrix block contributed by component. The 00091 * values are for the reverse direction. 00092 * @param isize,jsize number of rows and columns of matrix 00093 * block 00094 * @return false if network component does not contribute 00095 * matrix element 00096 */ 00097 virtual bool matrixReverseSize(int *isize, int *jsize) const; 00098 00099 /** 00100 * Return the values for an off-diagonl matrix block. The values are 00101 * for the reverse direction and are returned in row-major order. 00102 * @param values pointer to matrix block values 00103 * @return false if network component does not contribute 00104 * matrix element 00105 */ 00106 virtual bool matrixReverseValues(ComplexType *values); 00107 virtual bool matrixReverseValues(RealType *values); 00108 00109 /** 00110 * Return size of vector block contributed by component 00111 * @param isize number of vector elements 00112 * @return false if network component does not contribute 00113 * vector element 00114 */ 00115 virtual bool vectorSize(int *isize) const; 00116 00117 /** 00118 * Return the values of the vector block 00119 * @param values pointer to vector values 00120 * @return false if network component does not contribute 00121 * vector element 00122 */ 00123 virtual bool vectorValues(ComplexType *values); 00124 virtual bool vectorValues(RealType *values); 00125 00126 /** 00127 * Set values in the bus or branch component based on values in a vector or 00128 * matrix 00129 * @param values values in vector or matrix 00130 */ 00131 virtual void setValues(ComplexType *values); 00132 virtual void setValues(RealType *values); 00133 00134 /** 00135 * Set the matrix index for diagonal matrix components or vector component, 00136 * based on location of component in network 00137 * @param idx value of index 00138 */ 00139 void setMatVecIndex(int idx); 00140 00141 /** 00142 * Get the matrix index for diagonal matrix components or vector component, 00143 * based on location of component in network 00144 * @param value of index 00145 */ 00146 void getMatVecIndex(int *idx) const; 00147 00148 /** 00149 * Set the matrix indices for matrix components, based on location of component 00150 * in network 00151 * @param idx,jdx value of indices 00152 */ 00153 void setMatVecIndices(int idx, int jdx); 00154 00155 /** 00156 * Get the matrix indices for matrix components, * based on location of component 00157 * in network 00158 * @param idx,jdx value of indices 00159 */ 00160 void getMatVecIndices(int *idx, int *jdx) const; 00161 00162 //TODO: May need to include routines that support moving values from vectors 00163 // back into network components. 00164 00165 private: 00166 int p_ival, p_idx, p_jdx; 00167 00168 friend class boost::serialization::access; 00169 00170 template<class Archive> 00171 void serialize(Archive & ar, const unsigned int version) 00172 { 00173 ar & p_ival 00174 & p_idx 00175 & p_jdx; 00176 } 00177 00178 00179 }; 00180 00181 // ------------------------------------------------------------- 00182 // class GenMatVecInterface: 00183 // A general interface for defining matrices generated from 00184 // the network that do not follow the mapping of buses to 00185 // diagonal blocks and branches to off-diagonal blocks 00186 // ------------------------------------------------------------- 00187 00188 class GenMatVecInterface { 00189 public: 00190 /** 00191 * Constructor 00192 */ 00193 GenMatVecInterface(void); 00194 00195 /** 00196 * Destructor 00197 */ 00198 virtual ~GenMatVecInterface(void); 00199 00200 /** 00201 * Return number of rows in matrix from component 00202 * @return number of rows from component 00203 */ 00204 virtual int matrixNumRows() const; 00205 00206 /** 00207 * Return number of columns in matrix from component 00208 * @return number of columnsows from component 00209 */ 00210 virtual int matrixNumCols() const; 00211 00212 /** 00213 * Set row indices corresponding to the rows contributed by this 00214 * component 00215 * @param irow index of row contributed by this component (e.g. if component 00216 * contributes 3 rows then irow is between 0 and 2) 00217 * @param idx matrix index of row irow 00218 */ 00219 virtual void matrixSetRowIndex(int irow, int idx); 00220 00221 /** 00222 * Set column indices corresponding to the columns contributed by this 00223 * component 00224 * @param icol index of column contributed by this component (e.g. if component 00225 * contributes 3 columns then icol is between 0 and 2) 00226 * @param idx matrix index of column icol 00227 */ 00228 virtual void matrixSetColIndex(int icol, int idx); 00229 00230 /** 00231 * Get the row indices corresponding to the rows contributed by this component 00232 * @param irow index of row contributed by this component (e.g. if component 00233 * contributes 3 rows then irow is between 0 and 2) 00234 * @return matrix index of row irow 00235 */ 00236 virtual int matrixGetRowIndex(int irow); 00237 00238 /** 00239 * Get the column indices corresponding to the columns contributed by this component 00240 * @param icol index of column contributed by this component (e.g. if component 00241 * contributes 3 columns then icol is between 0 and 2) 00242 * @return matrix index of column icol 00243 */ 00244 virtual int matrixGetColIndex(int icol); 00245 00246 /** 00247 * Return the number of matrix values contributed by this component 00248 * @return number of matrix values 00249 */ 00250 virtual int matrixNumValues() const; 00251 00252 /** 00253 * Get a list of matrix values contributed by this component and their 00254 * matrix indices 00255 * @param values list of matrix element values 00256 * @param rows row indices for the matrix elements 00257 * @param cols column indices for the matrix elements 00258 */ 00259 virtual void matrixGetValues(ComplexType *values, int *rows, int*cols); 00260 virtual void matrixGetValues(RealType *values, int *rows, int*cols); 00261 00262 /** 00263 * Return number of elements in vector from component 00264 * @return number of elements contributed from component 00265 */ 00266 virtual int vectorNumElements() const; 00267 00268 /** 00269 * Set indices corresponding to the elements contributed by this 00270 * component 00271 * @param ielem index of element contributed by this component (e.g. if component 00272 * contributes 3 elements then ielem is between 0 and 2) 00273 * @param idx vector index of element ielem 00274 */ 00275 virtual void vectorSetElementIndex(int ielem, int idx); 00276 00277 /** 00278 * Get list of element indices from component 00279 * @param idx list of indices that component maps onto 00280 */ 00281 virtual void vectorGetElementIndices(int *idx); 00282 00283 /** 00284 * Get a list of vector values contributed by this component and their 00285 * indices 00286 * @param values list of vector element values 00287 * @param idx indices for the vector elements 00288 */ 00289 virtual void vectorGetElementValues(ComplexType *values, int *idx); 00290 virtual void vectorGetElementValues(RealType *values, int *idx); 00291 00292 /** 00293 * Transfer vector values to component 00294 * @param values list of vector element values 00295 */ 00296 virtual void vectorSetElementValues(ComplexType *values); 00297 virtual void vectorSetElementValues(RealType *values); 00298 00299 /** 00300 * Return number of rows and columns in matrix from component 00301 * Number of columns must be the same for all components 00302 * @return size of block contributed by component 00303 */ 00304 virtual void slabSize(int *rows, int *cols) const; 00305 00306 /** 00307 * Set indices corresponding to the rows contributed by this 00308 * component 00309 * @param irow index of row contributed by this component (e.g. if component 00310 * contributes 3 rows then irow is between 0 and 2) 00311 * @param idx row index of row irow 00312 */ 00313 virtual void slabSetRowIndex(int irow, int idx); 00314 00315 /** 00316 * Get list of row indices from component 00317 * @param idx list of row indices that component maps onto 00318 */ 00319 virtual void slabGetRowIndices(int *idx); 00320 00321 /** 00322 * Get a list of row values contributed by this component and their 00323 * indices 00324 * @param values list of values for rows 00325 * @param idx indices for the matrix rows 00326 */ 00327 virtual void slabGetValues(std::vector<ComplexType*> &values, int *idx); 00328 virtual void slabGetValues(std::vector<RealType*> &values, int *idx); 00329 00330 /** 00331 * Transfer slab values to component 00332 * @param values list of slab values 00333 */ 00334 virtual void slabSetValues(ComplexType **values); 00335 virtual void slabSetValues(RealType **values); 00336 00337 private: 00338 00339 friend class boost::serialization::access; 00340 00341 template<class Archive> 00342 void serialize(Archive & ar, const unsigned int version) 00343 { 00344 // yar; 00345 } 00346 00347 00348 }; 00349 00350 // ------------------------------------------------------------- 00351 // class BaseComponent: 00352 // This class implements some basic functions that can be 00353 // expected from any component on the network. 00354 // ------------------------------------------------------------- 00355 class BaseComponent 00356 : public MatVecInterface, public GenMatVecInterface { 00357 public: 00358 /** 00359 * Simple constructor 00360 */ 00361 BaseComponent(void); 00362 00363 /** 00364 * Destructor 00365 */ 00366 virtual ~BaseComponent(void); 00367 00368 /** 00369 * Load data from DataCollection object into corresponding 00370 * component. This needs to be implemented by every component 00371 * @param data data collection associated with component 00372 */ 00373 virtual void load( 00374 const boost::shared_ptr<gridpack::component::DataCollection> &data); 00375 00376 /** 00377 * Return the size of the buffer needed for data exchanges. Note that this 00378 * must be the same size for all bus and all branch objects (branch buffers 00379 * do not need to be the same size as bus buffers), even if all objects 00380 * do not require the same parameters. Thus, the buffer must be big enough 00381 * to exchange all variables that an object might need, even if individual 00382 * objects don't need all the variables 00383 * @return size of buffer 00384 */ 00385 virtual int getXCBufSize(void); 00386 00387 /** 00388 * Assign the location of the data exchange buffer. These buffers are 00389 * allocated and deallocated by the network 00390 * @param buf void pointer to exchange buffer 00391 */ 00392 virtual void setXCBuf(void *buf); 00393 00394 /** 00395 * Return the location of the data exchange buffer 00396 * @param buf void pointer to exchange buffer 00397 */ 00398 virtual void getXCBuf(void **bus); 00399 00400 /** 00401 * Set an internal variable that can be used to control the behavior of the 00402 * component. This function doesn't need to be implemented, but if needed, 00403 * it can be used to change the behavior of the network in different phases 00404 * of the calculation. For example, if a different matrix needs to be 00405 * generated at different times, the mode of the calculation can changed to 00406 * get different values from the MatVecInterface functions 00407 * @param mode integer indicating which mode should be used 00408 */ 00409 virtual void setMode(int mode); 00410 00411 /** 00412 * Copy a string for output into buffer. The behavior of this method can be 00413 * altered by inputting different values for the signal string 00414 * @param string buffer containing string to be written to output 00415 * @param bufsize size of string buffer in bytes 00416 * @param signal string to control behavior of routine (e.g. what 00417 * properties to write) 00418 * @return true if component is writing a contribution, false otherwise 00419 */ 00420 virtual bool serialWrite(char *string, const int bufsize, const char *signal = NULL); 00421 00422 /** 00423 * Save state variables inside the component to a DataCollection object. 00424 * This can be used as a way of moving data in a way that is useful for 00425 * creating output or for copying state data from one network to another. 00426 * @param data data collection object into which new values are inserted 00427 */ 00428 virtual void saveData(boost::shared_ptr<gridpack::component::DataCollection> 00429 data); 00430 00431 /** 00432 * Retrieve an opaque data item from component. Different items may be 00433 * returned based on the value of signal. 00434 * @param data item to retrieve from component 00435 * @param signal string to control behavior of routine (e.g. what 00436 * data item to return) 00437 * @return true if component is returning data element, false otherwise 00438 */ 00439 virtual bool getDataItem(void *data, const char *signal = NULL); 00440 00441 /** 00442 * Set rank holding the component 00443 * @param rank processor rank holding the component 00444 */ 00445 void setRank(int rank); 00446 00447 /** 00448 * Get rank holding the component 00449 * @return processor rank holding the component 00450 */ 00451 int getRank(void) const; 00452 00453 protected: 00454 /** 00455 * A buffer that can be used for exchanging component data. This is 00456 * allocated by the network based on an inquiry to the getXCBusSize method 00457 */ 00458 void *p_XCBuf; 00459 00460 /** 00461 * Size (in bytes) of buffer p_XCBuf 00462 */ 00463 int p_XCBufSize; 00464 00465 /** 00466 * Current mode 00467 */ 00468 int p_mode; 00469 00470 /** 00471 * Rank holding the component. Useful for debugging 00472 */ 00473 int p_rank; 00474 00475 private: 00476 00477 friend class boost::serialization::access; 00478 00479 /// Serialization "pack" routine 00480 template<class Archive> 00481 void save(Archive & ar, const unsigned int version) const 00482 { 00483 // p_XCBuf and p_XCBufSize are managed somewhere else; they will 00484 // have to be initialized 00485 ar << boost::serialization::base_object<MatVecInterface>(*this) 00486 << boost::serialization::base_object<GenMatVecInterface>(*this) 00487 << p_XCBufSize 00488 << p_mode; 00489 } 00490 00491 /// Serialization "unpack" routine 00492 template<class Archive> 00493 void load(Archive & ar, const unsigned int version) 00494 { 00495 ar >> boost::serialization::base_object<MatVecInterface>(*this) 00496 >> boost::serialization::base_object<GenMatVecInterface>(*this) 00497 >> p_XCBufSize 00498 >> p_mode; 00499 } 00500 00501 BOOST_SERIALIZATION_SPLIT_MEMBER() 00502 00503 }; 00504 00505 class BaseBusComponent 00506 : public BaseComponent { 00507 public: 00508 /** 00509 * Simple constructor 00510 */ 00511 BaseBusComponent(void); 00512 00513 /** 00514 * Simple destructor 00515 */ 00516 virtual ~BaseBusComponent(void); 00517 00518 /** 00519 * Add a pointer to the list of branches that a bus is connected to 00520 * @param branch pointer to a branch that is connected to bus 00521 */ 00522 void addBranch(const boost::shared_ptr<BaseComponent> & branch); 00523 00524 /** 00525 * Add a pointer to the list of buses that a bus is connected to via 00526 * a branch 00527 * @param bus pointer to a bus that is connected to bus via a branch 00528 */ 00529 void addBus(const boost::shared_ptr<BaseComponent> & bus); 00530 00531 /** 00532 * Get pointers to branches that are connected to bus 00533 * @param nghbrs list of pointers to neighboring branches 00534 */ 00535 void getNeighborBranches(std::vector<boost::shared_ptr<BaseComponent> > &nghbrs) const; 00536 00537 /** 00538 * Get pointers to buses that are connected to calling bus via a branch 00539 * @param nghbrs list of pointers to neighboring buses 00540 */ 00541 void getNeighborBuses(std::vector<boost::shared_ptr<BaseComponent> > &nghbrs) const; 00542 00543 /** 00544 * Clear all pointers to neighboring branches 00545 */ 00546 void clearBranches(void); 00547 00548 /** 00549 * Clear all pointers to neighboring buses 00550 */ 00551 void clearBuses(void); 00552 00553 /** 00554 * Set reference bus status 00555 * @param status reference bus status 00556 */ 00557 void setReferenceBus(bool status); 00558 00559 /** 00560 * Get reference bus status 00561 * @return true if bus is reference bus, false otherwise 00562 */ 00563 bool getReferenceBus(void) const; 00564 00565 /** 00566 * Set original index (from input file) 00567 * @param idx original index from network 00568 */ 00569 void setOriginalIndex(int idx); 00570 00571 /** 00572 * Get original index 00573 * @return original index from network 00574 */ 00575 int getOriginalIndex(void) const; 00576 00577 /** 00578 * Set global index 00579 * @param idx global index from network 00580 */ 00581 void setGlobalIndex(int idx); 00582 00583 /** 00584 * Get global index 00585 * @return global index from network 00586 */ 00587 int getGlobalIndex(void) const; 00588 00589 private: 00590 /** 00591 * Branches that are connect to bus 00592 */ 00593 std::vector<boost::weak_ptr<BaseComponent> > p_branches; 00594 /** 00595 * Buses that are connect to bus via a branch 00596 */ 00597 std::vector<boost::weak_ptr<BaseComponent> > p_buses; 00598 00599 /** 00600 * Is this a reference bus? 00601 */ 00602 bool p_refBus; 00603 00604 /** 00605 * Original and global indices, derived from network class 00606 */ 00607 int p_originalIndex; 00608 int p_globalIndex; 00609 00610 friend class boost::serialization::access; 00611 00612 template<class Archive> 00613 void serialize(Archive & ar, const unsigned int version) 00614 { 00615 ar & boost::serialization::base_object<BaseComponent>(*this) 00616 & p_refBus 00617 & p_originalIndex 00618 & p_globalIndex; 00619 00620 // p_branches and p_buses are ignored, but that may change 00621 } 00622 }; 00623 00624 class BaseBranchComponent 00625 : public BaseComponent { 00626 public: 00627 /** 00628 * Simple constructor 00629 */ 00630 BaseBranchComponent(void); 00631 00632 /** 00633 * Simple destructor 00634 */ 00635 virtual ~BaseBranchComponent(void); 00636 00637 /** 00638 * Set pointer to bus at one end of branch 00639 * @param bus pointer to bus 00640 */ 00641 void setBus1(const boost::shared_ptr<BaseComponent> & bus); 00642 00643 /** 00644 * Set pointer to bus at other end of branch 00645 * @param bus pointer to bus 00646 */ 00647 void setBus2(const boost::shared_ptr<BaseComponent> & bus); 00648 00649 /** 00650 * Get pointer to bus at one end of branch 00651 * @return pointer to bus 1 00652 */ 00653 boost::shared_ptr<BaseComponent> getBus1(void) const; 00654 00655 /** 00656 * Get pointer to bus at other end of branch 00657 * @return pointer to bus 2 00658 */ 00659 boost::shared_ptr<BaseComponent> getBus2(void) const; 00660 00661 /** 00662 * Clear bus pointers 00663 */ 00664 void clearBuses(void); 00665 00666 /** 00667 * Set global index for branch 00668 * @param idx global index of branch 00669 */ 00670 void setGlobalIndex(int idx); 00671 00672 /** 00673 * Set original index for bus 1 00674 * @param idx original index for bus 1 (assigned from input file) 00675 */ 00676 void setBus1OriginalIndex(int idx); 00677 00678 /** 00679 * Set original index for bus 2 00680 * @param idx original index for bus 2 (assigned from input file) 00681 */ 00682 void setBus2OriginalIndex(int idx); 00683 00684 /** 00685 * Set global index (from network) for bus 1 00686 * @param idx global index for bus 1 00687 */ 00688 void setBus1GlobalIndex(int idx); 00689 00690 /** 00691 * Set global index (from network) for bus 2 00692 * @param idx global index for bus 2 00693 */ 00694 void setBus2GlobalIndex(int idx); 00695 00696 /** 00697 * Get original index for bus 1 00698 * @return original index for bus 1 00699 */ 00700 int getBus1OriginalIndex(void) const; 00701 00702 /** 00703 * Get original index for bus 2 00704 * @return original index for bus 2 00705 */ 00706 int getBus2OriginalIndex(void) const; 00707 00708 /** 00709 * Get global index for bus 1 00710 * @return global index for bus 1 00711 */ 00712 int getBus1GlobalIndex(void) const; 00713 00714 /** 00715 * Get global index for bus 2 00716 * @return global index for bus 2 00717 */ 00718 int getBus2GlobalIndex(void) const; 00719 00720 /** 00721 * Get global index for branch 00722 */ 00723 int getGlobalIndex(void) const; 00724 00725 private: 00726 /** 00727 * Pointers to buses at either end of branch 00728 */ 00729 boost::weak_ptr<BaseComponent> p_bus1; 00730 boost::weak_ptr<BaseComponent> p_bus2; 00731 00732 /** 00733 * Original indices for bus 1 and bus 2 (assigned from input file) 00734 */ 00735 int p_originalBus1Index; 00736 int p_originalBus2Index; 00737 00738 /** 00739 * Global indices for bus 1 and bus 2 00740 */ 00741 int p_globalIndex; 00742 int p_globalBus1Index; 00743 int p_globalBus2Index; 00744 00745 friend class boost::serialization::access; 00746 00747 template<class Archive> 00748 void serialize(Archive & ar, const unsigned int version) 00749 { 00750 ar & boost::serialization::base_object<BaseComponent>(*this) 00751 & p_originalBus1Index 00752 & p_originalBus2Index 00753 & p_globalBus1Index 00754 & p_globalBus2Index; 00755 } 00756 00757 }; 00758 00759 } // component 00760 } // gridpack 00761 00762 BOOST_CLASS_EXPORT_KEY(gridpack::component::MatVecInterface) 00763 BOOST_CLASS_EXPORT_KEY(gridpack::component::BaseComponent) 00764 BOOST_CLASS_EXPORT_KEY(gridpack::component::BaseBusComponent) 00765 BOOST_CLASS_EXPORT_KEY(gridpack::component::BaseBranchComponent) 00766 00767 00768 #endif